/**
 * @description 路由拦截状态管理，目前两种模式：all模式与intelligence模式，其中partialRoutes是菜单暂未使用
 */
import {
  asyncRoutes,
  constantRoutes,
  resetRouter,
  developRoutes,
} from '@/router'
import { getRouterList } from '@/api/router'
import { filterRoutes } from '@/utils/routes'
import { authentication } from '@/config'
import auth from '@/plugins/auth'
import ParentView from '@/components/ParentView'
// import InnerLink from '@/layout/components/InnerLink'

const state = () => ({
  menu: { first: null },
  routes: [],
  cachedRoutes: [],
})
const getters = {
  menu: (state) => state.menu,
  routes: (state) => state.routes,
  cachedRoutes: (state) => state.cachedRoutes,
}
const mutations = {
  /**
   * @description 多模式设置路由
   * @param {*} state
   * @param {*} routes
   */
  setRoutes(state, routes) {
    state.routes = routes
  },
  /**
   * @description 设置缓存Name数组
   * @param {*} state
   * @param {*} routes
   */
  setCachedRoutes(state, routes) {
    state.cachedRoutes = routes
  },
  /**
   * @description 修改Meta
   * @param {*} state
   * @param options
   */
  changeMenuMeta(state, options) {
    function handleRoutes(routes) {
      return routes.map((route) => {
        if (route.name === options.name) Object.assign(route.meta, options.meta)
        if (route.children && route.children.length)
          route.children = handleRoutes(route.children)
        return route
      })
    }

    state.routes = handleRoutes(state.routes)
  },
}
const actions = {
  // 生成路由
  async setRoutes({ commit }) {
    const development = process.env.NODE_ENV === 'development'
    const finallyRoutes = [
      ...filterDynamicRoutes(asyncRoutes),
      ...constantRoutes,
      ...(development ? developRoutes : []),
    ]

    // 设置后端路由(不需要可以删除)
    if (authentication === 'all') {
      let res
      try {
        res = await getRouterList()
        localStorage.setItem('RuterInfo', JSON.stringify(res))
      } catch (error) {
        if (development) {
          res = JSON.parse(localStorage.getItem('RuterInfo'))
        }
      }

      if (!res) {
        reject('获取路由失败')
      }
      // 向后端请求路由数据
      const data = JSON.parse(JSON.stringify(res.data))
      if (data[data.length - 1].path !== '*') {
        data.push({ path: '*', redirect: '/404', hidden: true })
      }

      finallyRoutes.push(...convertRouter(data))
    }
    const data = filterRoutes(finallyRoutes)
    commit('setRoutes', data)
    await resetRouter(data)
  },

  /**
   * @description 设置缓存Name数组
   * @param {*} { commit }
   * @param {*} routes
   */
  setCachedRoutes({ commit }, routes) {
    commit('setCachedRoutes', routes)
  },
  /**
   * @description 修改Route Meta
   * @param {*} { commit }
   * @param options
   */
  changeMenuMeta({ commit }, options = {}) {
    commit('changeMenuMeta', options)
  },
}

export function convertRouter(asyncRoutes) {
  return asyncRoutes.map((route) => {
    if (route.component) {
      if (route.component === 'Layout') {
        route.component = (resolve) => require(['@/vab/layouts'], resolve)
      } else if (route.component === 'ParentView') {
        route.component = ParentView
      } else {
        route.component = loadView(route.component)
      }
    }
    if (route.children && route.children.length)
      route.children = convertRouter(route.children)
    if (route.children && route.children.length === 0) delete route.children
    return route
  })
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = []
  routes.forEach((route) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route)
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route)
      }
    }
  })
  return res
}

export const loadView = (view) => {
  if (process.env.NODE_ENV === 'development') {
    return (resolve) => require([`@/views/${view}`], resolve)
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/views/${view}`)
  }
}

export default { state, getters, mutations, actions }
